/*
*
* 版权所有 Copyleft(c) 2005
* 刘炯个人工作室 Sharp-Mark Personal Studio
*
* 允许自由使用，复制，修改，传播和贩卖此源程序及其文档，而不必支付任何费用。
* 以上的版权信息必须出现在每一份复制品中。同时这份版权信息和许可声明
* 也必须出现在支持文档中。刘炯个人工作室不对此软件适于那种具体
* 用途做出任何阐述。此代码只作为代码本身提供对其品质不做任何保证。
*
*/

// ChildView.cpp : CChildView 类的实现
//

#include "stdafx.h"
#include "Sierpinski.h"
#include "ChildView.h"
#include ".\childview.h"

#include "matrix.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CChildView

CChildView::CChildView()
{
	this->tick = 0;	// 颜色变化方案第一种
}

CChildView::~CChildView()
{
}


BEGIN_MESSAGE_MAP(CChildView, CWnd)
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()



// CChildView 消息处理程序

BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) 
{
	if (!CWnd::PreCreateWindow(cs))
		return FALSE;

	cs.dwExStyle |= WS_EX_CLIENTEDGE;
	cs.style &= ~WS_BORDER;
	cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, 
		::LoadCursor(NULL, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), NULL);

	return TRUE;
}

void CChildView::OnPaint() 
{
	CPaintDC dc(this);						// 用于绘制的设备上下文
	clock_t start, end;

	srand( ( unsigned ) time( 0 ) );		// 初始化随机数种子
	start = clock();

	// 获取客户区域矩形
	CRect rect;
	GetClientRect( &rect );
	
	// 三角形三个顶点
	POINT point [ 3 ];
	point[ 0 ].x = rect.Width() / 2;
	point[ 0 ].y = 0;

	point[ 1 ].x = 0;
	point[ 1 ].y = rect.Height() - 1;
	
	point[ 2 ].x = rect.Width() - 1;
	point[ 2 ].y = rect.Height() - 1;
	
	POINT p;								// 所要画的点的坐标

	// 点的初始化位置
	p.x = point[ 0 ].x;
	p.y = ( point[ 0 ].y + point[ 1 ].y ) / 2;

	int n;									// 顶点Index

	int r, g, b;							// 颜色的 R G B 参数
	int xColor, yColor;						// x, y轴颜色

	// 开始画点
	for ( int i = 0; i < 100000; i++ )
	{
		n = rand() % 3;						// 随机取顶点Index

		// 设置要画的点的坐标
		p.x = ( point[ n ].x + p.x ) / 2;
		p.y = ( point[ n ].y + p.y ) / 2;

		// 设定x, y轴颜色
		xColor = ( float )p.x / ( ( float )rect.Width() / 256 );
		yColor = ( float )p.y / ( ( float )rect.Height() / 256 );
		if( 0 == tick )						// 第一种颜色
		{
			r = xColor;
			g = yColor;
			b = 0;
		}
		else if ( 1 == tick )				// 第二种颜色
		{
			r = xColor;
			g = 0;
			b = yColor;
		}
		else								// 第三种颜色
		{
			r = 0;
			g = xColor;
			b = yColor;
		}

		dc.SetPixelV( p, RGB( r, g, b ) );	// 画点
	}

	end = clock();

	CString text;
	text.Format("The time was: %.5f", ((float)end - (float)start) / CLK_TCK);

	dc.TextOut(0, 0, text);

	/*
	Sierpinski(dc,"E:\\Projects\\MIT\\Graphics\\sierpinski_triangle.txt");
	Sierpinski(dc,"E:\\Projects\\MIT\\Graphics\\dragon.txt");
	Sierpinski(dc,"E:\\Projects\\MIT\\Graphics\\giant_x.txt");
	Sierpinski(dc,"E:\\Projects\\MIT\\Graphics\\fern.txt");
	*/
}


void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{
	tick = ( ++tick ) % 3;					// 颜色变化

	Invalidate();							// 窗体无效
	UpdateWindow();							// 重画窗体

	CWnd::OnLButtonDown(nFlags, point);
}

void CChildView::Sierpinski(CPaintDC& dc, char* filename)
{
	srand((unsigned)time(0));
	FILE *input = fopen(filename,"r");
	assert(input != NULL);

	int num_transforms; 
	fscanf(input,"%d",&num_transforms);

	Matrix* m = new Matrix[num_transforms];

	float* probability = new float[num_transforms];

	for (int i = 0; i < num_transforms; i++) {
		fscanf (input,"%f",&probability[i]);
		m[i].Read3x3(input);
	}

	for (int i =  num_transforms - 1; i > 0; i--)
		for(int j = 0; j < i; j++)
			probability[i] += probability[j];

	probability[0];
	probability[1];
	probability[2];

	Matrix po;

	for(int i = 0; i < 100000; i++)
	{
		po.Set(0, 0, rand() % 200);
		po.Set(0, 1, rand() % 200);
		po.Set(0, 3, 200);

		for(int k = 0; k < 4; k++)
		{
			float x = float(rand() % 100) / 100;

			int fi;// = rand() % 3;
			for(int n = 0; n < num_transforms; n++)
			{
				if ( x < probability[n])
				{
					fi = n;
					break;
				}
			}
			po = m[fi] * po;
		}
		Vec3f v(po.Get(0, 0), po.Get(0, 1), po.Get(0, 3));
		dc.SetPixelV(v.x() + 200, v.y() + 200, RGB(v.r(), v.g(), v.b()));
		//dc.SetPixelV((int)po.Get(0, 0), (int)po.Get(0, 1), RGB(100, 0, 0));
	}

	fclose(input);

	delete [] probability;
	delete [] m;
}